/*
 * ENUM Discoverer. ENUM Demonstration software, demonstrating the potential of ENUM.
 * 
 * Copyright (C) 2009 SIDN and ISOC.nl
 * 
 * This file is part of ENUM Discoverer.
 *
 * ENUM Discoverer is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * ENUM Discoverer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with ENUM Discoverer.  If not, see <http://www.gnu.org/licenses/>.
 */

package nl.sidn.enumdiscoverer.contacts.dao;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.TreeSet;

import nl.sidn.enumdiscoverer.contacts.ContactDetails;

/**
 * A PersonDao that stores all modifications in memory, and allows them to be written to a
 * PersonDao later
 * @author	Grant Patterson (grant.patterson@catalyst.net.nz)
 */
public class DelayedWritePersonDao extends PersonDao {
	
	private static final long NO_ID = -1;
	
	private final TreeSet<String> mEmailAddresses = new TreeSet<String>();
	private final ArrayList<ImPair> mImUrls       = new ArrayList<ImPair>();
	private final TreeSet<String> mPhoneNumbers   = new TreeSet<String>();
	private final TreeSet<String> mAddresses      = new TreeSet<String>();
	private final TreeSet<String> mOrganisations  = new TreeSet<String>();
	private HashMap<Integer, String> mLinks;
	private String mName;
	private byte[] mPhoto;
	private Coords mLocation;
	private String mPublicKey;
	private Date mBirthday;
	private String mSIPAddress;
	private String mStatus;
	
	public DelayedWritePersonDao() {
		super();
	}

	@Override
	public void addEmailAddress(String address) {
		mEmailAddresses.add(address);
	}

	@Override
	public void addInstantMessagingUrl(String imUrl, int protocol) {
		mImUrls.add(new ImPair(imUrl, protocol));
	}
	
	@Override
	public void setLocation(Coords location) {
		mLocation = location;
	}
	
	@Override
	public Coords getLocation() {
		return mLocation;
	}

	@Override
	public void addPhoneNumber(String number) {
		mPhoneNumbers.add(number);
	}
	
	@Override
	public void addPostalAddress(String address) {
		mAddresses.add(address);
	}
	
	@Override
	public String getPrimaryPostalAddress() {
		// just return the first address
		return mAddresses.first();
	}
	
	@Override
	public void addOrganisation(String organisation) {
		mOrganisations.add(organisation);
	}
	
	/**
	 * Does nothing. Any stored modifications will be thrown out.
	 * Use flushToContact() to write to Contacts
	 */
	@Override
	public void close() {}

	@Override
	public ContactDetails getDetails() {
		ContactDetails details = new ContactDetails();
		return details;
	}

	@Override
	public long getId() {
		return NO_ID;
	}
	
	/**
	 * Photo isn't in Contacts DB yet, so a stream cant' be provided
	 * @return null
	 */
	@Override
	public InputStream getPhoto() {
		return null;
	}

	@Override
	public HashMap<Integer, String> getWebLinks() {
		return mLinks;
	}

	@Override
	public String getSIPAddress() {
		return mSIPAddress;
	}

	@Override
	public String getStatus() {
		return mStatus;
	}

	@Override
	public void setName(String name) {
		mName = name;
	}

	@Override
	public void setPhoto(byte[] photoBytes) {
		mPhoto = photoBytes;
	}

	@Override
	public void setWebLinks(HashMap<Integer, String> links) {
		mLinks = links;
	}

	@Override
	public void setSipAddress(String address) {
		mSIPAddress = address;
	}
	@Override
	public void setStatus(String status) {
		mStatus = status;
	}

	/**
	 * Writes all modifications to personDao.
	 * @param personDao A PersonDao to write all stored modifications to
	 */
	public void flushToContact(PersonDao personDao) {
		
		for (String address : mEmailAddresses) {
			personDao.addEmailAddress(address);
		}
		
		for (ImPair im : mImUrls) {
			personDao.addInstantMessagingUrl(im.url, im.protocol);
		}
		
		for (String number : mPhoneNumbers) {
			personDao.addPhoneNumber(number);
		}
		
		for (String address : mAddresses) {
			personDao.addPostalAddress(address);
		}
		
		for (String org : mOrganisations) {
			personDao.addOrganisation(org);
		}

		if (mName != null) personDao.setName(mName);
		
		if (mPhoto != null) personDao.setPhoto(mPhoto);
		
		if (mLinks != null) personDao.setWebLinks(mLinks);

		if (mSIPAddress != null) personDao.setSipAddress(mSIPAddress);
		
		if (mLocation != null) personDao.setLocation(mLocation);
		
		if (mPublicKey != null) personDao.setPublicKey(mPublicKey);
		
		if (mBirthday != null) personDao.setDateOfBirth(mBirthday);
		
		if (mStatus != null) personDao.setStatus(mStatus);
	}
	
	private static class ImPair {
		String url;
		int protocol;
		ImPair(String url, int protocol) {
			this.url = url;
			this.protocol = protocol;
		}
	}

	@Override
	public String getPublicKey() {
		return mPublicKey;
	}

	@Override
	public void setPublicKey(String key) {
		mPublicKey = key;
	}

	@Override
	public Date getDateOfBirth() {
		return mBirthday;
	}

	@Override
	public void setDateOfBirth(Date birthday) {
		mBirthday = birthday;
	}
}
